package com.blue.config;

import com.blue.constant.JwtConstant;
import com.blue.pojo.Result;
import com.blue.pojo.User;
import com.blue.util.JacksonUtil;
import com.blue.util.JwtUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class LoginFilter extends AbstractAuthenticationProcessingFilter {
    private RedisTemplate jsonRedisTemplate;

    protected LoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager, RedisTemplate redisTemplate) {
        super(defaultFilterProcessesUrl);
        setAuthenticationManager(authenticationManager);
        this.jsonRedisTemplate = redisTemplate;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        User user = JacksonUtil.readValue(request.getInputStream(), User.class);

        return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        User user = (User) authResult.getPrincipal();
        user.setPassword(null);
        String jwt = JwtUtil.generateToken(user.getUsername());
        Map<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("token", jwt);
        jsonRedisTemplate.opsForHash().put(JwtConstant.REDIS_TOKEN_KEY, user.getUsername(), jwt);
        PrintWriter out = response.getWriter();
        out.write(JacksonUtil.writeValueAsString(Result.ok("登录成功", map)));
        out.flush();
        out.close();
    }


    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.setContentType("text/html;charset=UTF-8");
        String msg = exception.getMessage();
        if (exception instanceof LockedException) {
            msg = "账号被锁定";
        } else if (exception instanceof CredentialsExpiredException) {
            msg = "密码过期";
        } else if (exception instanceof AccountExpiredException) {
            msg = "账号过期";
        } else if (exception instanceof DisabledException) {
            msg = "账号被禁用";
        } else if (exception instanceof BadCredentialsException) {
            msg = "用户名或密码错误";
        }
        PrintWriter out = response.getWriter();
        out.write(JacksonUtil.writeValueAsString(Result.create(401, msg)));
        out.flush();
        out.close();
    }
}
